老人(病人)远程开门器

一、项目来由(讲一下人们在现实生活中遇到的问题,产生了制作什么项目的念头)

二、项目设计原理

三、项目设计思路(最好用流程图的形式表示出来这个项目是哪几部分功能构成的,每个部分的工作顺序等)

四、制作步骤(具体的制作过程,用编号表示出每一步的操作)

五、测试与效果(简述一下是否达到了预期的效果,如果有测试部分需要改进的,也可以写在这一部分里)

老人(病人)远程开门器

摘要

目前,中国的人口老龄化日益增加,老人独居已成为普遍现象。有些老人生病或者行动不便,在客人来访时或亲戚看望时不能及时开门,给他人带来不必要的麻烦和担忧。现有的门铃系统大多都装在大门旁,并且没有对讲或视频、人脸识别功能,往往不是十分方便。所以,我考虑设计一个远程的开门器,供生病卧床、行动不便的老人使用。或者在医院病房中,安装这样一个系统,在病人按紧急呼救铃时,护士能通过这样一个系统来了解目前病人的情况,初步作出判断,带上一些必须药品,尽量用最少的时间使病人得到救治。

这个远程开门器运用python编程进行设计,运用了client-server架构,分为client端和server端。

服务端即装在进户门处的装置,由摄像头,树莓派主机,按钮和电机驱动的开锁装置组成。摄像头装在进户门猫眼洞上,按钮开关装在进户门旁边的墙上。客户端目前为一台笔记本电脑,可以放在老人身边,进行实时监控。

关键词:远程控制,人脸识别,树莓派,Python编程

1.引言

1.1目前人口老龄化及老人独居情况

目前,在我国社会中,存在着较为普遍的老年人空巢化、失能化、高龄化特点,老年人口基数大,增长速度快,因而社会中面临的养老问题十分严峻。

图1

据统计,我国当前60岁以上老年人占比已经超过12%,预计每年增速将达到3%。根据相关预测,到2020年,我国老年人口占比将超过17%,到2050年,这一比例可能上升到30%。当前我国人均预期寿命已经超过了73岁,80岁以上老年人数量已经超过1600万,预计到2050年,高龄老年人数量将超过1亿,在全世界高龄老年人中,占比将达到25%。 图1独居老人抽样调查

1.2人口老龄化面临的主要问题

人口老龄化必然带来一些问题,包括医疗保障体制、老年照料服务体系、社会管理体制等,都面临着更大的挑战。

随着人口老龄化的不断发展,独居、病残、高龄老人的数量不断增加,老人一人在家已成普遍现象。有些老人行动不便,开门成了一个大问题。

老人随着年龄增长,去医院的次数也随之增加。医院人口多,医护工作繁忙,如何及时救治,如何免去一些小问题带来的麻烦,也成了一个又一个的问题。

1.3研究目的

根据目前人口老龄化面临的主要问题,设计出一个远程的开门器,应用于家中或者医院中。使老人不用费尽千辛万苦去开门,也可以使医疗救治更及时。

2.研究内容

2.1装置总体情况

这个远程开门器所创造的是一个虚拟环境。运用了client-server架构,分为client端和server端。

图2

Client端是电脑,通过server端(树莓派)实时拍摄下来的画面传输到电脑上,进行人脸识别,老人可通过显示的图片来看访客是谁,进而开门或不开。Server端是由摄像头,树莓派主机,按钮和电机驱动的开锁装置组成,进行实时的监控。流程图如图2所示。

图9

2.2 server端

图3

如图3所示,为远程开门器的服务器端。

图10

图11

图4

图3 server端

摄像头装在进户门猫眼洞上,按钮开关装在门上或门旁边的墙上。当有人按门铃(即按图中按钮)时,通过摄像头拍摄实时门口情况,传输至电脑,时长为20秒,最后定格为一张图片。如果老人按了“开门”,那么电机驱动的开锁装置就会旋转,模仿开门情况。

2.3 client端

将摄像头拍摄的画面显示在界面上,供老人看,然后选择是否开门。

图5

登录过程如图4所示

图12

图13

图6

登录后界面如图5、图6所示

图14

图15

图16

电脑端的登录步骤:

网络连接树莓派,获取IP地址,从putty输入IP

输入账号:pi

和密码:raspberry

输入指令:source~/.profile

进入虚拟环境

输入命令:cd eldermonitor

运行代码:python eldermonitor_server2018.py

打开代码eldermonitor_client2018.py

点“连接”,按树莓派的按钮

电脑端就会出现树莓派实时拍摄的画面,然后进行人脸识别,时长20秒

如果是认识的人,点“开门”,树莓派上的开锁装置就会旋转。

图7

人脸识别后界面如图6所示。

图17

3.总结与讨论

3.1独特之处

这个远程开门器相较于市面上普遍的开门装置,他更方便于行动不便的老人来开门。不需要走路,根据电脑上的图片,来开门,省去了走去开门所浪费的时间,也避免了因门外人等了很久也没来开门的担忧和麻烦。它所增加的人脸识别也可以更快捷的确定来访者是谁,应不应该开门。

其优点:方便快捷,可以远程控制。

3.2难点分析

人脸识别

计算机人脸识别技术是利用计算机对人脸图像进行分析和理解。这个程序中是基于OpenCv的人脸识别。OpenCv是一种用于数字图像处理和计算机视觉的函数库。它在Windows系统及Linux系统下都可以使用,它提供了针对各种形式的源文件的帧提取函数和很多标准的图像处理算法,主要用于对图像进行一些高级处理,具有很好的效率。

图8

人脸识别流程如图5所示。

4.展望

如果这个远程开门器运用到生活中的话,那么对于大多数老人来说是一个极大的便捷。在家庭中运用,有效的减少了亲属的担心。在医疗方面运用的话,有效的提高了治疗救治时间,可以减少一些医疗事故。但是,它也存在着问题,如果是一个盲人在使用怎么办?或者说,使用者眼睛看不清,怎么办?除了这两个功能,他是否可以用在老人与子女一起居住的家庭中呢?

对此,我的想法是:首先,在这个系统中加入语音播报功能,在人脸识别后,进行语音播报是谁,这个人是否在我认识的人中。其次,增加按照一定时间拍照储存的功能。如果在老人与子女一起居住的家庭中的话,假设子女也在家时,他可以用来实时监控外面的情况;或者假设这样一个场景,全家一起出游,回家后发现家里被盗,那么这个系统储存的照片就可以被翻出来,查看当时情况。

制作步骤:

图18

官网下载noobs

下载SD Card Formatter,后一路安装

图19

图20

快速格式化

图21

树莓派新版镜像开启摄像头的方法  首先连接摄像头 将排线插入CSI接口,有金属手指的一侧对着HDMI接口,插入到位以后将挡板按下。   连接好摄像头的效果   接下来是启用摄像头模块。 目前网上查询到的方法都是通过运行树莓派配置工具来激活摄像头模块: 输入 sudo raspi-config  移动光标至菜单中的 "Enable Camera(启用摄像头)",将其设为Enable(启用状态)。完成之后重启树莓派。    可是我使用的这版官网最新镜像压根就没有这个选项   也有网友说可以直接用,先使用vcgencmd get_camera 命令看看有没有发现摄像头吧   果然没有! 于是摸索着其他选项,发现有一个“5 interfacing options” 摄像头应该也属于接口设备,于是乎进去看看   果然发现一个就是“Camera”选项。果断选择camera    按回车打开,选择YES    成功启用摄像头。   要求重启,选择重启

如这张画面没出现,则在命令行中执行shutdown -r now 手工重启 重启以后运行vcgencmd get_camera 查看是否成功加载摄像头设备

图22

  OK!有摄像头了~! 拍摄一张照片试试看  sudo  raspistill -t 2000 -o image.jpg -w 640 -h 480     OK,运行成功,摄像头灯也亮了,打开照片查看,没问题   PS:因为相机是倒置的,所以图片反的。可以使用一些附加参数调整。 -rot, --rotation        : 设置图像旋转 (0到359) -hf, --hflip            : 设置水平翻转 horizontal flip -vf, --vflip            : 设置垂直翻转 vertical flip 例如翻转180度:sudo  raspistill -t 2000 -o image.jpg -w 640 -h 480 -rot 180  

好了,这下正过来了

5.附录

参考文献《机器视觉算法与运用》

代码:

Client端
from PIL import Image as PIL_Image
from PIL import ImageTk
from socket import *
from tkinter import *
from tkinter import messagebox
import time
import threading
import cv2
import numpy

isSocketConnect = 0
avg = None
cascPath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascPath)

# 连接Socket
def connectSocketClicked():
global socket
global isSocketConnect
try:
if (isSocketConnect == 0):
socket = socket(AF_INET, SOCK_STREAM)
socket.connect((valueHost.get(), valuePort.get()))
print("socket connected!!!")
isSocketConnect = 1
connectSocket.configure(bg="#00ff00")
thread1 = threading.Thread(target=SocketRecv)
thread1.start()
else:
messagebox.showinfo("Infomation", "The socket has been connected!")
except Exception as e:
print(e)
messagebox.showerror("Connection Error", "The server refuses to connect")

# 断开Socket
def disconnectSocketClicked():
global socket
global isSocketConnect
codeSocket = "S10000000"
try:
socket.send(bytearray(codeSocket, 'utf-8'))
connectSocket.configure(bg="#f0f0ed")
isSocketConnect = 0
socket.close()
except Exception as e:
print(e)
messagebox.showerror("Connection Error", "The socket has disconnection error")

# 开门指令
def openClicked():
global socket
codeSocket = "D10000000"
try:
socket.send(bytearray(codeSocket, 'utf-8'))
connectSocket.configure(bg="#f0f0ed")
except:
messagebox.showerror("Connection Error", "The socket has connection error")

# 接收数据
def recvall(sock, count):
buf = b''
while count:
newbuf = sock.recv(count)
if not newbuf:
return None
buf += newbuf
count -= len(newbuf)
return buf

# 处理Socket接收
def SocketRecv():
print("wait for data")
global socket
global isSocketConnect
thread_stop = 1
while (thread_stop):
try:
length = recvall(socket, 8)
msg = recvall(socket, int(length))
if not msg:
print("错误")
break
data = numpy.fromstring(msg, dtype='uint8')
img = cv2.imdecode(data, 1)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30)
)

print("Found {0} faces!".format(len(faces)))
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
tk_image = PIL_Image.fromarray(img).resize((480, 360))
tk_image = ImageTk.PhotoImage(tk_image)
Label(middleFrame, image=tk_image).grid(row=1, column=2, columnspan=6, rowspan=2, sticky=W + E + N + S,
padx=10, pady=10)
except Exception as e:
print(e)
thread_stop = 0
socket.close()

root = Tk()
root.title("Elder Monitor")
mainframe = Frame(root)
mainframe.pack()
titleFrame = Frame(mainframe)
titleFrame.grid(sticky=N)
Label(titleFrame, text='智能老人监护系统', font=("Times", "16", "bold")).grid(row=0, column=0)
Label(titleFrame, text=' Made by 金晓蕾', font=("Times", "14", "bold")).grid(row=1, column=0)
upFrame = LabelFrame(mainframe, text="Socket 连接", font=("Times", "12", "bold"), height=60, width=580, bd=4)
upFrame.grid(sticky=N, ipadx=30, ipady=5, padx=10, pady=10)
upFrame.grid_propagate(0)

Server端
camera = PiCamera()
camera.resolution = tuple([320, 240])
camera.framerate = 60
capture = PiRGBArray(camera, size=tuple([320, 240]))
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]

IN1 = 6
IN2 = 13
IN3 = 19
IN4 = 26
RingInput = 24
isRingBell = 0

def my_callback():
global isRingBell
global startTime
print("button pressed!")
isRingBell = 1
t = Timer(20.0)
t.start()

print("[INFO] warming up...")
time.sleep(2)
setup()
GPIO.add_event_detect(RingInput, GPIO.RISING, callback=my_callback, bouncetime=200)
HOST, PORT = "192.168.191.2", 7777
sock = socket(AF_INET, SOCK_STREAM)
print("Socket Made")
sock.bind((HOST, PORT))
print('Socket Bound, port: %d' % (PORT))
sock.listen(5)
print("Listening for connections...")
try:
dst, dst_addr = sock.accept()
isConnect = 1
thread1 = SocketReceiving()
thread1.start()
print("Socket Connected")
except Exception as e:
print(Exception, ":", e)
sock.close()
camera.close()

图23

图23

图24

图24